package com.bestom.waterquality.adapter;

import android.annotation.SuppressLint;
import android.hardware.usb.UsbDevice;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.appcompat.widget.SwitchCompat;
import androidx.fragment.app.FragmentActivity;
import androidx.recyclerview.widget.RecyclerView;

import com.bestom.waterquality.R;
import com.bestom.waterquality.entity.SerialBaudBean;
import com.bestom.waterquality.entity.SerialEntity;
import com.bestom.waterquality.ui.CustomTextView;
import com.bestom.waterquality.ui.SerialConfigDialog;
import com.bestom.waterquality.util.FormatUtil;
import com.bestom.waterquality.util.ToastUtil;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;

import cn.wch.ch934xlib.CH934XManager;
import cn.wch.ch934xlib.exception.ChipException;
import cn.wch.ch934xlib.exception.UartLibException;
import cn.wch.ch934xlib.utils.LogUtil;

public class SerialListAdapter extends RecyclerView.Adapter<SerialListAdapter.MyViewHolder> {

    private FragmentActivity activity;
    private ArrayList<SerialEntity> serialEntities;
    private HashMap<Integer, Integer> writeCountMap;

    public SerialListAdapter(@NonNull FragmentActivity activity, @NonNull ArrayList<SerialEntity> serialEntities) {
        this.activity=activity;
        this.serialEntities = serialEntities;
        writeCountMap=new HashMap<>();
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new MyViewHolder(LayoutInflater.from(activity).inflate(R.layout.serial_item,parent,false));
    }

    private Handler mHandler;
    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        SerialEntity serialEntity = serialEntities.get(position);
        writeCountMap.put(serialEntity.getSerialNumber(),0);
        holder.tvDescription.setText(String.format(Locale.getDefault(),"串口%d",serialEntity.getSerialNumber()));
        final SerialBaudBean[] mSerialBaudBean = {null};
        //设置串口
        holder.setSerial.setOnClickListener(v -> {
            SerialConfigDialog dialog=SerialConfigDialog.newInstance(mSerialBaudBean[0]);
            dialog.setCancelable(false);
            dialog.show(activity.getSupportFragmentManager(),SerialConfigDialog.class.getName());
            dialog.setListener(data -> {
                if(setSerialParameter(serialEntity.getUsbDevice(),serialEntity.getSerialNumber(),data )){
                    holder.serialInfo.setText(data.toString());
                    mSerialBaudBean[0] = data;
                    showToast("设置成功");
                }else {
                    showToast("设置失败");
                }
            });
        });
        //定时发送
        holder.scWrite.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
                if (mHandler == null){

                    mHandler = new Handler(){
                        @Override
                        public void handleMessage(Message msg) {
                            if (b){
                                if (holder.serialInfo.getText().equals("未设置串口参数,请设置--->")) {
                                    showToast("请先设置串口参数!");
                                    holder.scWrite.setChecked(false);
                                    return;
                                }
                                if (holder.serialInfo.getText().equals("未设置串口参数,请设置--->")) {
                                    showToast("请先设置串口参数!");
                                    return;
                                }

                                String s = holder.writeBuffer.getText().toString();
                                if(TextUtils.isEmpty(s)){
                                    showToast("发送内容为空");
                                    return;
                                }
                                if(!s.matches("([0-9|a-f|A-F]{2})*")){
                                    showToast("发送内容不符合HEX规范");
                                    return;
                                }
                                byte[] bytes = FormatUtil.hexStringToBytes(s);

                                int ret = writeData(serialEntity.getUsbDevice(), serialEntity.getSerialNumber(), bytes, bytes.length);
                                if(ret>=0){
                                    //更新发送计数
                                    int writeCount = getWriteCount(serialEntity.getSerialNumber());
                                    writeCount+=ret;
                                    setWriteCount(serialEntity.getSerialNumber(),writeCount);
                                    holder.writeCount.setText(String.format(Locale.getDefault(),"发送计数：%d字节",writeCount));
                                }
                                long l = Long.parseLong(holder.serialInfo.getText().toString().split("定时")[1]);
                                this.postDelayed(() -> sendEmptyMessage(1),l*1000);
                            }
                        }
                    };
                }
                if (b){
                    mHandler.sendEmptyMessage(1);
                }else {
                    mHandler.removeCallbacksAndMessages(null);
                    mHandler = null;
                }
            }
        });
        //发送
        holder.write.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (holder.serialInfo.getText().equals("未设置串口参数,请设置--->")) {
                    showToast("请先设置串口参数!");
                    return;
                }

                String s = holder.writeBuffer.getText().toString();
                if(TextUtils.isEmpty(s)){
                    showToast("发送内容为空");
                    return;
                }
                if(!s.matches("([0-9|a-f|A-F]{2})*")){
                    showToast("发送内容不符合HEX规范");
                    return;
                }
                byte[] bytes = FormatUtil.hexStringToBytes(s);
                /*if(holder.scWrite.isChecked()){

                }else {
                    bytes = s.getBytes(StandardCharsets.UTF_8);
                }*/
                int ret = writeData(serialEntity.getUsbDevice(), serialEntity.getSerialNumber(), bytes, bytes.length);
                if(ret>=0){
                    //更新发送计数
                    int writeCount = getWriteCount(serialEntity.getSerialNumber());
                    writeCount+=ret;
                    setWriteCount(serialEntity.getSerialNumber(),writeCount);
                    holder.writeCount.setText(String.format(Locale.getDefault(),"发送计数：%d字节",writeCount));
                    showToast("发送成功");
                }else {
                    showToast("发送失败");
                }
            }
        });
        holder.clearWrite.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                setWriteCount(serialEntity.getSerialNumber(),0);
                holder.writeBuffer.setText("");
                holder.writeCount.setText(String.format(Locale.getDefault(),"发送计数：%d字节",getWriteCount(serialEntity.getSerialNumber())));
            }
        });
    }

    @Override
    public int getItemCount() {
        return serialEntities==null? 0:serialEntities.size();
    }

    public SerialEntity get(int position){
        return serialEntities==null? null :serialEntities.get(position);
    }


    public static class MyViewHolder extends RecyclerView.ViewHolder{
        TextView tvDescription;
        TextView serialInfo;
        CustomTextView setSerial;

        TextView write;
        CustomTextView clearWrite;
        SwitchCompat scWrite;
        TextView writeCount;


        EditText writeBuffer;

        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
            tvDescription=itemView.findViewById(R.id.tvSerialDescription);
            serialInfo=itemView.findViewById(R.id.tvSerialInfo);
            setSerial=itemView.findViewById(R.id.tvSerialConfig);
            write=itemView.findViewById(R.id.tvWrite);
            writeBuffer=itemView.findViewById(R.id.send_data);
            writeCount=itemView.findViewById(R.id.tvWriteCount);

            clearWrite=itemView.findViewById(R.id.tvClearWrite);

            scWrite=itemView.findViewById(R.id.scWrite);

        }
    }
    //设置串口参数
    boolean setSerialParameter(UsbDevice usbDevice,int serialNumber,SerialBaudBean baudBean){
        try {
            boolean b = CH934XManager.getInstance().setSerialParameter(usbDevice, serialNumber,
                    baudBean.getBaud(), baudBean.getData(), baudBean.getStop(), baudBean.getParity(),baudBean.isFlow());
            return b;
        } catch (UartLibException | ChipException e) {
            LogUtil.d(e.getMessage());
        }
        return false;
    }
    //写数据
    int writeData(UsbDevice usbDevice,int serialNumber,@NonNull byte[] data,int length){
        try {
            int write = CH934XManager.getInstance().writeData(usbDevice, serialNumber, data, length,2000);

            return write;
        } catch (UartLibException | ChipException e) {
            LogUtil.d(e.getMessage());

        }
        return -2;
    }

    public int getWriteCount(int serialNumber){
        return writeCountMap.get(serialNumber);
    }

    public void setWriteCount(int serialNumber,int newValue){
        writeCountMap.put(serialNumber,newValue);
    }

    void showToast(String message){
        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                ToastUtil.create(activity,message).show();
            }
        });
    }

}
